import datetime
import json

import hashlib
import time

from django.core.cache import cache
from django.http import JsonResponse
import collections

from comment.log_code import LogCodes
from utils.tokens import TIME_OUT

allow_active = ["login", "signin"]
salt = "JXU2NDkyJXU2MjUzJXU3Qjk3JXU2MjUz"


def server_time():
    return "%d" % int(time.time())


def response_change(response):
    response["Access-Control-Allow-Origin"] = "*"
    response["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"
    response["Access-Control-Max-Age"] = "1000"
    response["Access-Control-Allow-Headers"] = "*"
    response["Access-Control-Allow-Credentials"] = True
    return response


def err_resp(code, message):
    resp = dict()
    resp["code"] = code
    resp["message"] = message
    resp["data"] = None
    resp["server_time"] = server_time()
    resp["success"] = 0
    return response_change(JsonResponse(resp))


"""
token=c289f7ddb95675f7a2a87bd13c09c3a7&
time=1546779029&
salt=JXU2NDkyJXU2MjUzJXU3Qjk3JXU2MjUz&
params={"platform":"Google","remarks":"","pwuser":"test123","pwdata":"123456","user":"15299112b7ce4d988870a57e63c32efb"}&
apiName=create
"""


def check_token(params, uid, signature, time, api_name):
    body = {}
    token = cache.get(uid)
    if token is None:
        return False
    
    body["token"] = cache.get(uid)
    body["salt"] = salt
    body["time"] = time
    body["params"] = params
    body["apiName"] = api_name
    body_str = ""
    body_list = sorted(body.items(), key=lambda x: x[0], reverse=True)
    for param in body_list:
        body_str += "{}={}&".format(param[0], str(param[1]))
    body_str = body_str[:-1]
    token = hashlib.sha256(body_str.encode()).hexdigest()
    print(body_str)
    print(token)
    if token == signature:
        # cache.set(uid, token, TIME_OUT)
        return True
    return False


def check_appinfo():
    pass


def check_time(timeDateStr):
    # time1 = datetime.datetime.strptime(timeDateStr, "%Y-%m-%d %H:%M:%S")
    #     # seconds = time.mktime(time1.timetuple())
    try:
        seconds = int(timeDateStr)
    except Exception as e:
        return -1
    # seconds = time.time()
    sub_time = (time.time() - seconds)
    if sub_time > 180000000:
        return None
    return seconds


def com_views(requests, func_map):
    body = None
    try:
        body = json.loads(requests.body.decode())
    except Exception as e:
        return err_resp(LogCodes.PARAMS_EMPTY, "format is not json")
    
    active = requests.GET.get("active")
    app_info = body.get("appInfo")
    time = body.get("time")
    time = check_time(time)
    if time is None:
        return err_resp(LogCodes.TIME_TOOLONG, "time is too long to get response")
    elif time == -1:
        return err_resp(LogCodes.TIME_TOOLONG, "time format is error")
    params = body.get("params")
    
    signature = body.get("signature")
    uid = body.get("uid")
    if not all([params, app_info, time, active]):
        return err_resp(LogCodes.PARAMS_EMPTY, "params is None")
    
    # 如果不在白名单中
    if not active in allow_active:
        
        if not all([signature, uid]):
            return err_resp(LogCodes.PARAMS_EMPTY, "params is None")
        
        if check_token(params, uid, signature, time, active) == False:
            return err_resp(LogCodes.LOGIN_ERROR, "signature is error")
    else:
        if cache.has_key(uid):
            cache.delete(uid)
    try:
        if isinstance(params, str):
            params = json.loads(params)
        elif isinstance(params, dict):
            pass
        else:
            return err_resp(LogCodes.PARAMS_EMPTY, "params format is not json")
    except Exception as e:
        return err_resp(LogCodes.PARAMS_EMPTY, "params format is not json")
    
    result = func_map.get(active)(params)
    if result:
        resp = dict(zip(["code", "message", "data", "success", "server_time"], result))
        return response_change(JsonResponse(resp))
    else:
        return err_resp(LogCodes.PARAMS_ERROR, "active is empty")
